﻿using SistemaAdministracion.Models;
using SistemaAdministracion.Models.Authentication;
using SistemaAdministracion.Models.BaseClass;
using SistemaAdministracion.Models.PatternBase;
using SistemaAdministracion.Models.ViewModels.Account;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace SistemaAdministracion.Controllers
{
    public class AccountController : Controller
    {
        //Declaracion del patron Reposity y Unit of work
        //y cosas por el estilo
        IDbContext _context;
        UnitOfWork _UoW;
        IRepository<Usuario> _repUser;
        IRepository<Role> _repRole;
        IRepository<UsuarioRol> _repUserRole;
        CustomMembershipProvider MembershipServices;


        public AccountController()
        {
            //Inicializamos patron
            MembershipServices = new CustomMembershipProvider();
            _context = new DbContextAdapter(ContextBase.ContextBaseInstance);
            _UoW = new UnitOfWork(_context);
            _repUser = new BaseRepository<Usuario>(_context);
            _repRole = new BaseRepository<Role>(_context);
            _repUserRole = new BaseRepository<UsuarioRol>(_context);
        }
        
        //
        // GET: /Account/
        [AllowAnonymous]
        public ActionResult Login()
        { 
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        //Metodo Login de Usuario
        public ActionResult Login(LoginUserModel userModel)
        {
            if (ModelState.IsValid)
            {
                if (MembershipServices.ValidateUser(userModel.UserName, userModel.Password))
                {
                    SetupFormsAuthTicket(userModel.UserName, false);
                    return RedirectToAction("Inicio", "Enterprise");
                }

            }
            ViewBag.Error = "Usuario Invalido o No Existe";
            return View();
        }
        //Metodo que crea un ticket de autentificacion
        private Usuario SetupFormsAuthTicket(string userName, bool persistanceFlag)
        {
            Usuario user = _repUser.SingleOrDefault(u => u.UserName == userName);
            var userId = user.IdUser;
            var userData = userId.ToString(CultureInfo.InvariantCulture);
            var authTicket = new FormsAuthenticationTicket(1, //version
                                userName, // nombre de usuario
                                DateTime.Now,             //creacion
                                DateTime.Now.AddMinutes(30), //Expiracion
                                persistanceFlag, //persistencia si es recordado o no 
                                userData);

            var encTicket = FormsAuthentication.Encrypt(authTicket); //<-- encripta el ticket autentificado
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)); //<--- añade a la respuesta un nuevo cookie con el nombre y el ticket
            return user;
        }

        [HttpPost]
        [Authorize]
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Login", "Account");
        }

        [Authorize(Roles = "Administrador")]
        public ActionResult Register()
        {
            
            return View(new UserRoleViewModel());
        }

        [HttpPost]
        [Authorize(Roles = "Administrador")]
        public ActionResult Register(UserRoleViewModel userModel)
        {
            if (ModelState.IsValid) //<--- identificamos si el modelo que nos envia el formulario esta correcto
            {
                MembershipCreateStatus Final; //<--- variable que recibe del metodo siguiente create user y obtiene como valor Success o Error dependiendo de la operacion
                //Creamos un usuario a traves membership provider 
                MembershipUser MemberUs = MembershipServices.CreateUser(userModel.RegisterModel.UserName, userModel.RegisterModel.Password, userModel.RegisterModel.Email, string.Empty, string.Empty, true, null, out Final);
                //confirmamos si la variable es identica a success de status.Sucess
                if (Final == MembershipCreateStatus.Success)
                {
                    Usuario us = _repUser.SingleOrDefault(u => u.UserName == userModel.RegisterModel.UserName);
                    foreach (var item in userModel.CheckRoles)
                    {
                        if (item.Selected)
                        {
                            Role rl = _repRole.SingleOrDefault(r => r.NombreRol == item.rolName);
                            UsuarioRol usr = new UsuarioRol() { idRole = rl.IdRole, idUser = us.IdUser, User = us, Role = rl };
                            _repUserRole.Add(usr);
                            _UoW.Commint(); 
                        }
                       
                    }
                    //relacionamos usuario con rol, UsuarioRol
                    
                    
                    return RedirectToAction("Index", "Home");
                }
            }
            return View();
        }


    }
}